package com.framework.core.date.old;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author Xu.MinZhe
 * @version V1.0
 * @Project payment
 * @Package com.lang
 * @Description
 * @Date 2018/1/30 11:49
 */
public class DateUtil {
    /**
     * 格式化日期
     *
     * @param date 日期
     * @param pattern 格式
     * @return 格式化字符串
     */
    public static String format(Date date, String pattern) {
        if (date != null && StringUtils.isNotBlank(pattern)) {
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            format.setLenient(true);
            return format.format(date);
        }
        return null;
    }

    /**
     * 尝试将日期字符串解析成日期对象
     * <p>该方法将依次尝试patterns中所有的格式，直到第一个成功为止。</p>
     * <p>该方法不会抛出异常，当所有的格式都解析失败将返回<code>null</code></p>
     *
     * @param date 日期字符串
     * @param patterns 尝试的格式
     * @return 返回解析的日期对象，如果所有的格式都失败，则返回<code>null</code>
     */
    public static Date parseDate(String date, String... patterns) {
        if (StringUtils.isNotBlank(date) && patterns.length > 0) {
            for (String ptn : patterns) {
                try {
                    SimpleDateFormat format = new SimpleDateFormat(ptn);
                    format.setLenient(false);
                    return format.parse(date);
                } catch (ParseException e) {
                }
            }
        }
        return null;
    }

    /**
     * 解析日期字符串为日期对象
     *
     * @param date 日期字符串
     * @param pattern 日期格式
     * @return
     * @throws ParseException 解析失败
     */
    public static Date parseDate(String date, String pattern) throws ParseException {
        if (StringUtils.isNotBlank(date) && StringUtils.isNotBlank(pattern)) {
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            format.setLenient(false);
            return format.parse(date);
        }
        return null;
    }

    /**
     * 加上天数
     *
     * @param date 日期
     * @param day 天数
     * @return
     */
    public static Date addDays(Date date, int day) {
        return date == null ? null : new Date(date.getTime() + 24 * 60 * 60 * 1000l * day);
    }

    /**
     * 加上小时
     *
     * @param date 日期
     * @param hours 小时
     * @return
     */
    public static Date addHours(Date date, int hours) {
        return date == null ? null : new Date(date.getTime() + 60 * 60 * 1000l * hours);
    }

    /**
     * 加上分钟
     *
     * @param date 日期
     * @param minutes 分钟
     * @return
     */
    public static Date addMinutes(Date date, int minutes) {
        return date == null ? null : new Date(date.getTime() + 60 * 1000l * minutes);
    }

    /**
     * 加上秒数
     *
     * @param date 日期
     * @param seconds 秒
     * @return
     */
    public static Date addSeconds(Date date, int seconds) {
        return date == null ? null : new Date(date.getTime() + 1000l * seconds);
    }

    /**
     * 加上自然月
     * <p>
     * 例子：2014-01-31 + 1个月  = 2014-02-28
     * </p>
     *
     * @param date
     * @param months
     * @return
     */
    public static Date addNatureMonths(Date date, int months) {
        if (date != null && months != 0) {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(Calendar.MONTH, months);
            return c.getTime();
        }
        return date;
    }

    /**
     * 以合同的方式加上月份
     * <p>比如 1.31 加上 1 个月 = 2.28</>
     *
     * @param date
     * @param months
     * @return
     */
    public static Date addContractMonths(Date date, int months) {
        if (date != null && months != 0) {
            Calendar c = Calendar.getInstance();
            c.setTime(date);

            int day = c.get(Calendar.DAY_OF_MONTH);

            c.add(Calendar.MONTH, months);
            if (day == c.get(Calendar.DAY_OF_MONTH)) {
                c.add(Calendar.DAY_OF_MONTH, -1);
            }
            return c.getTime();
        }
        return date;
    }

    /**
     * 获取纯净的日期对象,一天的最早时间
     * <p>
     * <p>该方法将会把日期对象的HOUR,MINUTE,SECOND,MILLISECOND置0</p>
     *
     * @param date 日期
     * @return 一天的最早时间
     */
    public static Date getPureDay(Date date) {
        if (date != null) {
            Calendar cl = Calendar.getInstance();
            cl.setTime(date);
            cl.set(Calendar.HOUR_OF_DAY, 0);
            cl.set(Calendar.MINUTE, 0);
            cl.set(Calendar.SECOND, 0);
            cl.set(Calendar.MILLISECOND, 0);
            return cl.getTime();
        }
        return date;
    }

    /**
     * 获取一天的最晚时间
     *
     * @param date 日期
     * @return
     */
    public static Date getTailDay(Date date) {
        if (date != null) {
            Calendar cl = Calendar.getInstance();
            cl.setTime(date);
            cl.set(Calendar.HOUR_OF_DAY, 23);
            cl.set(Calendar.MINUTE, 59);
            cl.set(Calendar.SECOND, 59);
            cl.set(Calendar.MILLISECOND, 999);
            return cl.getTime();
        }
        return date;
    }

    /**
     * 获取月份起始日期
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getMinMonthDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 日期比较
     *
     * @param date1 日期1
     * @param date2 日期2
     * @return
     */
    public static int compare(Date date1, Date date2) {
        if (date1 == null && date2 == null) {
            return 0;
        } else if (date1 == null) {
            return -1;
        } else if (date2 == null) {
            return 1;
        }
        return date1.getTime() < date2.getTime() ? -1 : date1.getTime() == date2.getTime() ? 0 : 1;
    }

    /**
     * 是否是未来的时间
     *
     * @param date
     * @return
     */
    public static boolean isFuture(Date date) {
        return date != null && date.getTime() > System.currentTimeMillis();
    }

    /**
     * 是否是今天
     *
     * @param date
     * @return
     */
    public static boolean isToday(Date date) {
        return date != null && DateUtil.format(date, "yyyyMMdd").equals(DateUtil.format(new Date(), "yyyyMMdd"));
    }

    /**
     * 获取日期小的对象
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Date getMin(Date date1, Date date2) {
        if (date1 != null && date2 != null) {
            return date1.getTime() < date2.getTime() ? date1 : date2;
        }
        return null;
    }

    /**
     * 获取日期大的对象
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Date getMax(Date date1, Date date2) {
        if (date1 != null && date2 != null) {
            return date1.getTime() > date2.getTime() ? date1 : date2;
        }
        return null;
    }

    /**
     * 获取日期相差的月数
     *
     * @param start 开始时间
     * @param end 结束时间
     * @param tailUp 不足一天是否算一天
     * @return
     */
    public static int getOffsetMonths(Date start, Date end, boolean tailUp) {
        if (start != null && end != null) {
            long offsetMills = end.getTime() - start.getTime();
            return (int) (offsetMills / (1000l * 60 * 60 * 24 * 30) + (
                    !tailUp || offsetMills % (1000l * 60 * 60 * 24 * 30) == 0 ? 0 : (offsetMills > 0 ? 1 : -1)));
        }
        return 0;
    }

    /**
     * 获取日期相差的天数
     *
     * @param start 开始时间
     * @param end 结束时间
     * @param tailUp 不足一天是否算一天
     * @return
     */
    public static int getOffsetDays(Date start, Date end, boolean tailUp) {
        if (start != null && end != null) {
            long offsetMills = end.getTime() - start.getTime();
            return (int) (offsetMills / (1000l * 60 * 60 * 24) + (!tailUp || offsetMills % (1000l * 60 * 60 * 24) == 0 ?
                    0 :
                    (offsetMills > 0 ? 1 : -1)));
        }
        return 0;
    }

    /**
     * 获取距离当前时间的相差天数
     * <p>
     * now-date相差天数
     * </p>
     *
     * @param date 日期
     * @param tailUp 不足一天是否算一天
     * @return
     */
    public static int getOffsetNowDays(Date date, boolean tailUp) {
        if (date != null) {
            return getOffsetDays(date, new Date(), tailUp);
        }
        return 0;
    }

    /**
     * 获取时间相差的分钟数
     *
     * @param start 开始时间
     * @param end 结束时间
     * @param tailUp 不足一天是否算一天
     * @return
     */
    public static int getOffsetMinutes(Date start, Date end, boolean tailUp) {
        if (start != null && end != null) {
            long offsetMills = end.getTime() - start.getTime();
            return (int) (offsetMills / (1000l * 60) + (!tailUp || offsetMills % (1000l * 60) == 0 ?
                    0 :
                    (offsetMills > 0 ? 1 : -1)));
        }
        return 0;
    }

    /**
     * 获取距离当前时间相差的分钟数
     * <p>
     * <p>
     * now - date
     * </p>
     *
     * @param date
     * @param tailUp 不足一天是否算一天
     * @return
     */
    public static int getOffsetNowMinutes(Date date, boolean tailUp) {
        return getOffsetMinutes(new Date(), date, tailUp);
    }

    /**
     * 获取日期相差的小时数
     *
     * @param start 开始时间
     * @param end 结束时间
     * @param tailUp 不足一天是否算一天
     * @return
     */
    public static int getOffsetHours(Date start, Date end, boolean tailUp) {
        if (start != null && end != null) {
            long offsetMills = end.getTime() - start.getTime();
            return (int) (offsetMills / (1000l * 60 * 60) + (!tailUp || offsetMills % (1000l * 60 * 60) == 0 ?
                    0 :
                    (offsetMills > 0 ? 1 : -1)));
        }
        return 0;
    }

    /**
     * 获取距离当前时间相加的小时数
     * <p>
     * <p>
     * now - date
     * </p>
     *
     * @param date
     * @param tailUp
     * @return
     */
    public static int getOffsetNowHours(Date date, boolean tailUp) {
        return getOffsetHours(new Date(), date, tailUp);
    }

    /**
     * 获取下一个工作日
     *
     * @param date
     * @return
     */
    public static Date getNextWeekday(Date date) {
        if (date != null) {
            Calendar c = Calendar.getInstance();
            c.setTime(date);

            int week = c.get(Calendar.DAY_OF_WEEK);
            if (Calendar.SATURDAY == week) {
                return addDays(date, 2);
            } else if (Calendar.SUNDAY == week) {
                return addDays(date, 1);
            }
            return date;
        }
        return null;
    }

    /**
     * 获取时间差
     *
     * @param date1
     * @param date2
     * @return
     */
    public static String getHumanOffset(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("日期不能为空");
        }
        long offset = Math.abs(date2.getTime() - date1.getTime());
        long day = offset / (24 * 3600 * 1000);
        long hour = (offset - day * 24 * 3600 * 1000) / (3600 * 1000);
        long minute = (offset - day * 24 * 3600 * 1000 - hour * 3600 * 1000) / (60 * 1000);
        String msg = "";

        int len = 0;
        if (day > 0) {
            len++;
            msg += day + "天";
        }
        if (day > 0 || hour > 0) {
            len++;
            msg += hour + "时";
        }
        if (len < 2) {
            msg += minute + "分";
        }
        return msg;
    }

    /**
     * 是否是成年人
     *
     * @param birthday
     * @return
     */
    public static boolean isAudit(int birthday) {
        if (birthday >= 19000101 && birthday <= 20991231) {
            try {
                Date birth = DateUtil.parseDate(Integer.toString(birthday), "yyyyMMdd");
                return compare(DateUtil.addNatureMonths(birth, 18 * 12), new Date()) <= 0;
            } catch (ParseException e) {
                return false;
            }
        }
        return false;
    }

    public static String getLastDay(String datadate)throws Exception{
        Date date = null;
        String day_last = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        date = format.parse(datadate);

        //创建日历
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);    //加一个月
        calendar.set(Calendar.DATE, 1);     //设置为该月第一天
        calendar.add(Calendar.DATE, -1);    //再减一天即为上个月最后一天
        day_last = format.format(calendar.getTime());
        return day_last;
    }

    public static String getFirstDay(String datadate)throws Exception{
        Date date = null;
        String day_first = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        date = format.parse(datadate);

        //创建日历
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        day_first = format.format(calendar.getTime());
        return day_first;
    }

    /**
     *时间戳转为日期
     * @param time
     * @return
     * @throws ParseException
     */
    public static Date LongToDate(long time) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String d = format.format(time);
        Date date = format.parse(d);
        return date;
    }

    //判断选择的日期是否是本周
    public static boolean isThisWeek(long time) {
        Calendar calendar = Calendar.getInstance();
        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        calendar.setTime(new Date(time));
        int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        if(paramWeek==currentWeek){
            return true;
        }
        return false;
    }
}
